package com.longyiqun.cm.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableMap;
import com.longyiqun.cm.MockServer;
import com.longyiqun.cm.domain.BaseServerEntity;
import com.longyiqun.cm.domain.CleanScriptEntity;
import com.longyiqun.cm.domain.ServerEntity;
import com.longyiqun.cm.domain.TestCaseEntity;
import com.longyiqun.cm.mapper.CasesMapper;
import com.longyiqun.cm.mapper.CleanScriptMapper;

import com.longyiqun.cm.mapper.ServerMapper;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.JobWithDetails;

import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URL;
import java.sql.*;
import java.util.*;

/**
 * program: CaseManager
 * package: com.longyiqun.cm.service
 * author: 龙轶群
 * create: 2018-03-23 19:31
 **/

@Service
public class CasesServiceImpl implements CasesService {

    @Autowired
    private CasesMapper casesMapper;


    @Autowired
    private CleanScriptMapper cleanScriptMapper;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public PageInfo getModuleForPaging(int pageIndex, int pageNum, String ID, String module, String selectType) {
        PageHelper.startPage(pageIndex, pageNum);
        if (selectType == null || selectType.equals("0")) {
            List<TestCaseEntity> list = casesMapper.findAllCases();
            logger.error("Get Cases: " + list.size());
            PageInfo page = new PageInfo(list);
            return page;
        } else {
            if (ID != "0" && ID != "") {
                ArrayList<TestCaseEntity> list = new ArrayList<>();
                TestCaseEntity testCaseEntity = casesMapper.findOne(ID);

                if (testCaseEntity !=null) {
                    list.add(testCaseEntity);
                    logger.error("Get Case ID: " + testCaseEntity.getId());
                    PageInfo page = new PageInfo(list);
                    return page;
                } else {
                    PageInfo page = new PageInfo();
                    return page;
                }
            } else {
                if (module == "") {
                    List<TestCaseEntity> list = casesMapper.findAllCases();
                    logger.error("Get Cases: " + list.size());
                    PageInfo page = new PageInfo(list);
                    return page;
                } else {
                    List<TestCaseEntity> list = casesMapper.findCasesByModule(module);
                    logger.error("Get Case: " + list.size());
                    PageInfo page = new PageInfo(list);
                    return page;
                }
            }
        }
    }
    @Override
    public PageInfo getServerForPaging(int pageIndex, int pageNum, String Leader, String Platform, String ServerName,String selectType) {
        String path = null;
        try {
            path = ResourceUtils.getURL("").getPath();
            // System.out.println(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        PageHelper.startPage(pageIndex, pageNum);
        if (selectType == null || selectType.equals("0")) {
            List<ServerEntity> list = casesMapper.findAllServer();
            logger.error("Get Cases: " + list.size());
            PageInfo page = new PageInfo(list);
            return page;
        } else {

            if (Leader != ""||Platform != ""||ServerName != "") {
                Leader = "%"+Leader+"%";
                Platform = "%"+Platform+"%";
                ServerName = "%"+ServerName+"%";
                List<ServerEntity> list = casesMapper.findServerByLike(Leader,Platform,ServerName);
                PageInfo page = new PageInfo(list);
                return page;
            }else {
                List<ServerEntity> list = casesMapper.findAllServer();
                logger.error("Get Cases: " + list.size());
                PageInfo page = new PageInfo(list);
                return page;
            }
        }
    }



    @Override
    public PageInfo getModuleForPaging(int pageIndex, int pageNum, String ID, String module, String selectType, String sortName, String sortOrder) {
        PageHelper.startPage(pageIndex, pageNum);
        if (selectType == null || selectType.equals("0")) {
            List<TestCaseEntity> list = casesMapper.findAllCasesOrderBy(sortName, sortOrder);
            logger.error("Get Cases: " + list.size());
            PageInfo page = new PageInfo(list);
            return page;
        } else {
            if (ID != "0" && ID != "") {
                ArrayList<TestCaseEntity> list = new ArrayList<>();
                TestCaseEntity testCaseEntity = casesMapper.findOne(ID);
                list.add(testCaseEntity);
                logger.error("Get Case ID: " + testCaseEntity.getId());
                PageInfo page = new PageInfo(list);
                return page;
            } else {
                if (module == "") {
                    List<TestCaseEntity> list = casesMapper.findAllCases();
                    logger.error("Get Cases: " + list.size());
                    PageInfo page = new PageInfo(list);
                    return page;
                } else {
                    List<TestCaseEntity> list = casesMapper.findCasesByModule(module);
                    logger.error("Get Case: " + list.size());
                    PageInfo page = new PageInfo(list);
                    return page;
                }
            }
        }
    }



    @Override
    public TestCaseEntity findOne(String caseID) {
        return casesMapper.findOne(caseID);
    }

    @Override
    public int updateOne(TestCaseEntity testCaseEntity) {
        return casesMapper.updateCases(testCaseEntity);
    }

    @Override
    public int addOne(TestCaseEntity testCaseEntity) {
        return casesMapper.addCases(testCaseEntity);
    }

    @Override
    public int deleteOne(int caseID) {
        return casesMapper.deleteCases(caseID);
    }

    @Override
    public String mockOne(String caseID, String env) {
        TestCaseEntity t = casesMapper.findOne(caseID);
        return MockServer.mock(t, env);
    }

    @Override
    public int runAll(String env) {
        try {
            JenkinsServer jenkins = new JenkinsServer(new URI("http://192.168.200.41:8088"), "admin", "admin");
            JobWithDetails jobWithDetails = jenkins.getJob("RunAllCases");
            System.out.println(jobWithDetails.getUrl()+")))))))000");
            if(jobWithDetails.isBuildable()) {

                HashMap<String, String> params = new HashMap<String, String>();
                params.put("env",env);
                jobWithDetails.build(params, false);
            }
//            int S = CleanData("all",env);
            return 0;

        } catch (Exception e) {
            return 1;
        }
    }

    @Override
    public int runModule(String moduleName, String env) {
        try {
            JenkinsServer jenkins = new JenkinsServer(new URI("http://192.168.200.41:8088"), "admin", "admin");
            JobWithDetails jobWithDetails = jenkins.getJob("RunModule");
            if(jobWithDetails.isBuildable()) {

//                final ImmutableMap<String, String> params = ImmutableMap.of(parameterNameForJob, moduleName);

                HashMap<String, String> params = new HashMap<String, String>();
                params.put("moduleName", moduleName);
                params.put("env",env);

                // 此处有坑, 只能用2个参数的方法, 单个参数, Run两遍Job
                jobWithDetails.build(params, false);
            }
            String param ="module,"+moduleName;
            int S = CleanData(param,env);
            return 0;

        } catch (Exception e) {
            return 1;
        }
    }

    @Override
    public int runSingle(String ids, String env) {
        try {
            JenkinsServer jenkins = new JenkinsServer(new URI("http://192.168.200.41:8088"), "admin", "admin");
            JobWithDetails jobWithDetails = jenkins.getJob("RunSingleCases");
            if(jobWithDetails.isBuildable()) {

                HashMap<String, String> params = new HashMap<String, String>();
                params.put("caseSingleIDs", ids);
                params.put("env", env);

                // 此处有坑, 只能用2个参数的方法, 单个参数, Run两遍Job
                jobWithDetails.build(params, false);
            }
//            int S = CleanData(ids,env);
            return 0;

        } catch (Exception e) {
            return 1;
        }
    }

    @Override
    public int runScene(String id, String env) {
        try {
            JenkinsServer jenkins = new JenkinsServer(new URI("http://192.168.200.41:8088"), "admin", "admin");
            JobWithDetails jobWithDetails = jenkins.getJob("RunScene");
            if(jobWithDetails.isBuildable()) {

                HashMap<String, String> params = new HashMap<String, String>();
                params.put("sceneID", id);
                params.put("env", env);

                jobWithDetails.build(params, false);
            }

            return 0;

        } catch (Exception e) {
            return 1;
        }
    }
    @Override
    public int CleanData(String ids,String env){
        if (ids.length()>5){
            System.out.println(ids);
            if(ids.contains("module")){
                String[] module = ids.split(",");
                //System.out.println(module[1]+"---module");
                List Entity = casesMapper.findCasesByModule(module[1]);
                // System.out.println("Size:::a"+Entity.size());
                ids = "";
                for (int i=0;i<Entity.size();i++){
                    TestCaseEntity Case = (TestCaseEntity) Entity.get(i);
                    ids = ids + Case.getId().toString() +",";
                }
                System.out.println("String::"+ids);
                //ids = ids.substring(1,ids.length()-1);
                System.out.println(ids);
            }
        }

        if (ids =="all"){
            List Entity = casesMapper.findAllCases();
            ids = "";
            for (int i=0;i<Entity.size();i++){
                TestCaseEntity Case = (TestCaseEntity) Entity.get(i);
                ids = ids+Case.getId().toString() +",";
            }
            ids = ids.substring(0,ids.length()-1);
            System.out.println(ids);
        }
        // System.out.println(ids+"*****************") ;
        CleanScriptEntity cleaner = cleanScriptMapper.runModuleSQL("财务工作台", env);
        String[] CaseIDArray ;
        if (ids.contains(",")){
            CaseIDArray = ids.split(",");
            //System.out.println("拼接"+ids);
        }else {
            CaseIDArray= new String[]{ids};
        }
        System.out.println("CaseIDArray"+CaseIDArray);
        for (int i=0;i<CaseIDArray.length;i++){
            System.out.println(CaseIDArray[i]);
            TestCaseEntity Remark = casesMapper.findOne(CaseIDArray[i]);
            System.out.println("+++"+Remark.getRemark()+"***");
            if(Remark.getRemark().length()> 6){
                String update= Remark.getRemark().substring(0,6);
                if (update.equals("update")){
                    System.out.println("++++++++++++");
                    cleaner.setScript(Remark.getRemark());
                    String Remarks = Remark.getRemark();
                    RunScript(cleaner);
                }
            }

        }
        return 0;
    }

    @Override
    public int runModuleSQL(String moduleName, String env) {
        // 0 - 成功  1 - 执行失败  2 - 无脚本
        CleanScriptEntity cleaner = cleanScriptMapper.runModuleSQL(moduleName, env);
        if (cleaner == null) {
            return 2;
        } else {
            return RunScript(cleaner);
        }

    }

    @Override
    public String isFinish(int jobID) {
        try {
            if(jobID <=0){
                throw new IllegalArgumentException("jodId must greater than 0!");
            }
            JenkinsServer jenkins = new JenkinsServer(new URI("http://192.168.200.41:8080"), "admin", "admin");
            JobWithDetails jobWithDetails = jenkins.getJob("RunAllCases");
            boolean isFinish = jobWithDetails.getLastBuild().details().isBuilding();
            if (isFinish) {
                return "true";
            } else {
                return "false";
            }

        } catch (Exception e) {
            return "false";
        }
    }

    @Override
    public String getCaseRemark(int caseID) {
        return casesMapper.getCaseRemark(caseID);
    }

    private int RunScript(CleanScriptEntity cleaner) {

        String script = cleaner.getScript() ;
        String connectString = cleaner.getConnectstring();
        String userName = cleaner.getUsername();
        String pwd = cleaner.getPwd();

        Connection con = null;
        System.out.println(script);
        String[] scriptStr = script.split("#");
        script = scriptStr[0];
        String[] sqls = script.split(";");

        try {

            // 获得数据库连接
            con = getConnection(connectString, userName, pwd);

            // 执行一批SQL语句
            int[] results = goBatch(con, sqls);

            // 分析执行的结果
            for (int i = 0; i < sqls.length; i++) {
                if (results[i] >= 0) {
                    System.out.println("语句: " + sqls[i] + " 执行成功，影响了"
                            + results[i] + "行数据");
                } else if (results[i] == Statement.SUCCESS_NO_INFO) {
                    System.out.println("语句: " + sqls[i] + " 执行成功，影响的行数未知");
                } else if (results[i] == Statement.EXECUTE_FAILED) {
                    System.out.println("语句: " + sqls[i] + " 执行失败");
                }
            }

            return 0;
        } catch (Exception ex) {

            return 1;
        }
    }

    // 数据库连接
    public static Connection getConnection(String connectString, String userName, String pwd) {
        Connection con = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection(connectString, userName, pwd);
        } catch (Exception e) {
            System.out.println("数据库连接失败");
        }
        return con;
    }

    // 执行一批SQL语句
    private static int[] goBatch(Connection con, String[] sqls) throws Exception {
        if (sqls == null) {
            return null;
        }
        Statement sm = null;
        try {
            sm = con.createStatement();
            for (int i = 0; i < sqls.length; i++) {
                sm.addBatch(sqls[i]);// 将所有的SQL语句添加到Statement中
            }
            // 一次执行多条SQL语句
            return sm.executeBatch();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            sm.close();
        }
        return null;
    }

}
